package com.nc.delivery_project.client.users;

import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.*;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.ListDataProvider;
import com.nc.delivery_project.client.add_user.AddUserPlace;
import com.nc.delivery_project.client.user_details.UserDetailsPlace;
import com.nc.delivery_project.shared.proxy.UserProxy;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * Created by miroshnik on 12/28/2014.
 */
public class UsersView extends Composite {
    interface UserViewUiBinder extends UiBinder<VerticalPanel, UsersView> {
    }

    private static UserViewUiBinder uiBinder = GWT.create(UserViewUiBinder.class);

    private ListDataProvider<UserProxy> dataProvider;
    
    private List<UserProxy> dataList;

    ColumnSortEvent.ListHandler<UserProxy> sortHandler;
    
    @UiField
    VerticalPanel panel;
    
    @UiField
    TextBox filterTxtBox;

    @UiField
    DataGrid<UserProxy> usersDataGrid;
    
    @UiField
    SimplePager pager;

    @UiField
    Button addBtn;

    private UsersPresenter presenter;
    
    public UsersView() {
        initWidget(uiBinder.createAndBindUi(this));
    }

    public void setPresenter(UsersPresenter presenter) {
        this.presenter = presenter;
    }

    public void start() {
        panel.setCellWidth(usersDataGrid, "100%");
        panel.setCellWidth(pager, "100%");

        usersDataGrid.setWidth("100%");
        usersDataGrid.setHeight("400px");
        usersDataGrid.setEmptyTableWidget(new HTML("No Data to Display"));

        pager.setDisplay(usersDataGrid);

        dataProvider = new ListDataProvider<>();
        dataProvider.setList(new ArrayList<UserProxy>());
        
        sortHandler = new ColumnSortEvent.ListHandler<>(dataProvider.getList());

        initTableColumns(usersDataGrid, sortHandler);

        usersDataGrid.addColumnSortHandler(sortHandler);

        dataProvider.addDataDisplay(usersDataGrid);

        filterTxtBox.addKeyUpHandler(new KeyUpHandler() {
            @Override
            public void onKeyUp(KeyUpEvent event) {
                filter(filterTxtBox.getText());
            }
        });

        addBtn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                presenter.goTo(new AddUserPlace(""));
            }
        });
    }

    private void filter(String filteredEmail) {
        List<UserProxy> filteredUsers = new ArrayList<>();
        for (UserProxy user : dataList) {
            if (user.getEmail().contains(filteredEmail)) {
                filteredUsers.add(user);
            }
        }
        
        bindData(filteredUsers);
    }

    public void initTableColumns(DataGrid<UserProxy> dataGrid, ColumnSortEvent.ListHandler<UserProxy> sortHandler) {
        Column<UserProxy, String> idCol = createIdCol(sortHandler);
        Column<UserProxy, String> emailCol = createEmailCol(sortHandler);
        Column<UserProxy, String> roleCol = createRoleCol(sortHandler);
        Column<UserProxy, String> userDetailsBtnCol = createDetailsBtnCol();

        dataGrid.addColumn(idCol, "ID");
        dataGrid.addColumn(emailCol, "Email");
        dataGrid.addColumn(roleCol, "Role");
        dataGrid.addColumn(userDetailsBtnCol, "Details");
    }

    private Column<UserProxy, String> createRoleCol(ColumnSortEvent.ListHandler<UserProxy> sortHandler) {
        Column<UserProxy, String> col = new Column<UserProxy, String>(new TextCell()) {
            @Override
            public String getValue(UserProxy object) {
                return object.getRole().getTitle();
            }
        };
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<UserProxy>() {
            @Override
            public int compare(UserProxy o1, UserProxy o2) {
                return o1.getRole().getTitle().compareToIgnoreCase(o2.getRole().getTitle());
            }
        });
        return col;
    }

    private Column<UserProxy, String> createEmailCol(ColumnSortEvent.ListHandler<UserProxy> sortHandler) {
        Column<UserProxy, String> col = new Column<UserProxy, String>(new EditTextCell()) {
            @Override
            public String getValue(UserProxy object) {
                return object.getEmail();
            }
        };
        
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<UserProxy>() {
            @Override
            public int compare(UserProxy o1, UserProxy o2) {
                return o1.getEmail().compareToIgnoreCase(o2.getEmail());
            }
        });

        return col;
    }

    private Column<UserProxy, String> createIdCol(ColumnSortEvent.ListHandler<UserProxy> sortHandler) {
        Column<UserProxy, String> col = new Column<UserProxy, String>(new TextCell()) {
            @Override
            public String getValue(UserProxy object) {
                return String.valueOf(object.getId());
            }
        };
        
        col.setSortable(true);
        sortHandler.setComparator(col, new Comparator<UserProxy>() {
            @Override
            public int compare(UserProxy o1, UserProxy o2) {
                if (o1.getId() == o2.getId()) {
                    return 0;
                } else {
                    return o1.getId() > o2.getId() ? 1 : -1;
                }
            }
        });
        return col;
    }
    
    private Column<UserProxy, String> createDetailsBtnCol() {
        Column<UserProxy, String> detailsBtnCol = new Column<UserProxy, String>(new ButtonCell()) {
            @Override
            public String getValue(UserProxy object) {
                return "->";
            }
        };
        detailsBtnCol.setFieldUpdater(new FieldUpdater<UserProxy, String>() {
            @Override
            public void update(int index, UserProxy object, String value) {
                presenter.goTo(new UserDetailsPlace(String.valueOf(dataProvider.getList().get(index).getId())));
            }
        });
        return detailsBtnCol;
    }

    public void setDataList(List<UserProxy> dataList) {
        this.dataList = dataList;
        bindData(dataList);
    }
    
    public void bindData(List<UserProxy> users) {
        dataProvider.setList(users);
        sortHandler.setList(dataProvider.getList());
        dataProvider.refresh();
    }
}